package ua.vn.ticket_scanner.ui.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.nfc.NfcAdapter;
import android.nfc.NfcManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import ua.vn.ticket_scanner.R;
import ua.vn.ticket_scanner.network.data.ConnectResult;
import ua.vn.ticket_scanner.network.data.JSONKeys;
import ua.vn.ticket_scanner.network.task.http.BlockValidatorsTask;
import ua.vn.ticket_scanner.network.utils.ResultRunnable;
import ua.vn.ticket_scanner.ui.AnimationListener;
import ua.vn.ticket_scanner.user.UserData;
import ua.vn.ticket_scanner.utils.VibratorHelper;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    private static final int MENU_LOGIN_ITEM_POSITION = 0;

    private ProgressBar mScanProgressBar;
    private TextView mLogoText;
    private TextView mScanningText;
    private TextView mControllerInfoText;
    private ProgressBar mProgressBar;

    private Menu mMenu;

    private boolean areMenuButtonLocked = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mLogoText = (TextView) findViewById(R.id.logoText);
        mScanProgressBar = (ProgressBar) findViewById(R.id.scanningProgressBar);
        mScanningText = (TextView) findViewById(R.id.scanningTextView);
        mControllerInfoText = (TextView) findViewById(R.id.controllerInfo);
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);

        Log.i(TAG, "onCreate");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        mMenu = menu;
        updateMenu();
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_login:
                if (UserData.getInstance().isLogined()) {
                    UserData.getInstance().clear();
                    updateMenu();
                    animShowSuccess(getString(R.string.message_logout_complete));
                    animShowSuperError(getString(R.string.message_need_to_login));
                }
                else
                    startActivity(new Intent(this, LoginActivity.class));
                return true;
            case R.id.menu_block_validaros:
                if (!areMenuButtonLocked)
                    blockValidators(true);
                return true;
            case R.id.menu_unblock_validaros:
                if (!areMenuButtonLocked)
                    blockValidators(false);
                return true;
            case R.id.menu_settings:
                startActivity(new Intent(this, SettingsActivity.class));
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume");
        checkErrors();
        updateControllerInfo();
        updateMenu();
    }

    @Override
    protected void onPause() {
        super.onPause();
        VibratorHelper.cancelVibro();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mScanProgressBar = null;
        mLogoText = null;
        mScanningText = null;
        mControllerInfoText = null;
        mProgressBar = null;
        mMenu = null;
    }

    private void updateControllerInfo() {
        String firstName = UserData.getInstance().getFirstName();
        String secondName = UserData.getInstance().getSecondName();
        String result = firstName == null ? "..." : firstName;
        result += " - ";
        result += secondName == null ? "..." : secondName;
        mControllerInfoText.setText(result);
    }

    private void updateMenu() {
        if (mMenu != null) {
            if (UserData.getInstance().isLogined())
                mMenu.getItem(MENU_LOGIN_ITEM_POSITION).setTitle(R.string.menu_logout);
            else
                mMenu.getItem(MENU_LOGIN_ITEM_POSITION).setTitle(R.string.menu_login);
        }
    }

    private void lock(boolean isLock) {
        areMenuButtonLocked = isLock;
        if (isLock) {
            mProgressBar.setVisibility(View.VISIBLE);
        } else {
            mProgressBar.setVisibility(View.INVISIBLE);
        }
    }

    private void checkErrors() {
        NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
        NfcAdapter adapter = manager.getDefaultAdapter();
        if (adapter == null) {
            // Device doesn't have NFC
            setScanning(false);
            animShowSuperError(getResources().getString(R.string.message_nfc_isnt));
        } else {
            if (!adapter.isEnabled()) {
                // NFC isn't enable
                setScanning(false);
                animShowSuperError(getResources().getString(R.string.message_switch_on_nfc));
            } else {
                setScanning(true);
                if (UserData.getInstance().isLogined()) {
                    hideSuperError();
                } else {
                    animShowSuperError(getResources().getString(R.string.message_need_to_login));
                }
            }
        }
    }

    private void setScanning(boolean scanning) {
        if (scanning) {
            mScanProgressBar.setVisibility(View.VISIBLE);
            mScanningText.setVisibility(View.VISIBLE);
            mLogoText.setVisibility(View.VISIBLE);
        } else {
            mScanProgressBar.setVisibility(View.GONE);
            mScanningText.setVisibility(View.GONE);
            mLogoText.setVisibility(View.INVISIBLE);
        }
    }

    private void blockValidators(final boolean isNeedToBlock) {
        lock(true);
        BlockValidatorsTask blockTask = new BlockValidatorsTask(isNeedToBlock);
        blockTask.setOnPostExecute(new ResultRunnable() {
            @Override
            public void run() {

                MainActivity activity = MainActivity.this;
                if (activity == null)
                    return;

                lock(false);
                if (mConnectResult == null) {
                    String message = getResources().getString(R.string.message_validators_not_unblocked);
                    message += "\n" + getResources().getString(R.string.message_connect_failed);
                    animShowError(message);
                    return;
                }
                String error_code = mConnectResult.get(JSONKeys.ERROR_CODE);
                String message;
                if (error_code == null) {
                    if (isNeedToBlock)
                        message = getResources().getString(R.string.message_validators_blocked);
                    else
                        message = getResources().getString(R.string.message_validators_unblocked);
                    animShowSuccess(message);
                } else {
                    if (isNeedToBlock)
                        message = getResources().getString(R.string.message_validators_not_blocked);
                    else
                        message = getResources().getString(R.string.message_validators_not_unblocked);
                    message += "\n" + ConnectResult.errorCodes.get(error_code);
                    animShowError(message);
                }
            }
        });
        blockTask.execute();
    }

    private final Runnable checkErrorsRunnable = new Runnable() {
        @Override
        public void run() {
            MainActivity activity = MainActivity.this;
            if (activity != null)
                activity.checkErrors();
        }
    };

    private void animShowError(String message) {
        VibratorHelper.doubleShortVibro();
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.error);
        TextView text = (TextView) findViewById(R.id.errorText);
        text.setText(message);

        Animation anim = AnimationUtils.loadAnimation(this, R.anim.effect_show_throw);
        AnimationListener animationListener = new AnimationListener(layout, checkErrorsRunnable);
        anim.setAnimationListener(animationListener);
        layout.startAnimation(anim);
    }

    private void animShowSuccess(String message) {
        VibratorHelper.shortVibro();
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.success);
        TextView text = (TextView) findViewById(R.id.successText);
        text.setText(message);

        Animation anim = AnimationUtils.loadAnimation(this, R.anim.effect_show_throw);
        AnimationListener animationListener = new AnimationListener(layout, checkErrorsRunnable);
        anim.setAnimationListener(animationListener);
        layout.startAnimation(anim);
    }

    private void animShowSuperError(String message) {
        VibratorHelper.repeatShortVibro();
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.superError);
        TextView text = (TextView) findViewById(R.id.superErrorText);
        text.setText(message);

        layout.startAnimation(AnimationUtils.loadAnimation(this, R.anim.effect_show_blink));
        layout.setVisibility(View.VISIBLE);
    }

    private void hideSuperError() {
        VibratorHelper.cancelVibro();
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.superError);
        Animation oldAnim = layout.getAnimation();
        if (oldAnim == null || oldAnim.hasEnded()) {
            layout.setVisibility(View.GONE);
            return;
        }
        Animation anim = AnimationUtils.loadAnimation(this, R.anim.effect_show_hide);
        AnimationListener animationListener = new AnimationListener(layout, null);
        anim.setAnimationListener(animationListener);
        layout.startAnimation(anim);
    }
}
